package com.hello.sandbox.fake.delegate;

import android.app.IServiceConnection;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import black.android.app.BRIServiceConnectionO;
import java.util.HashMap;
import java.util.Map;
import com.hello.sandbox.utils.compat.BuildCompat;

/** Created by Milk on 4/2/21. * ∧＿∧ (`･ω･∥ 丶　つ０ しーＪ 此处无Bug */
public class ServiceConnectionDelegate extends IServiceConnection.Stub {
  private static final Map<IBinder, ServiceConnectionDelegate> sServiceConnectDelegate =
      new HashMap<>();
  private final IServiceConnection mConn;
  private final ComponentName mComponentName;

  private ServiceConnectionDelegate(IServiceConnection mConn, ComponentName targetComponent) {
    this.mConn = mConn;
    this.mComponentName = targetComponent;
  }

  public static ServiceConnectionDelegate getDelegate(IBinder iBinder) {
    return sServiceConnectDelegate.get(iBinder);
  }

  public static IServiceConnection createProxy(IServiceConnection base, Intent intent) {
    final IBinder iBinder = base.asBinder();
    ServiceConnectionDelegate delegate = sServiceConnectDelegate.get(iBinder);
    if (delegate == null) {
      try {
        iBinder.linkToDeath(
            new IBinder.DeathRecipient() {
              @Override
              public void binderDied() {
                sServiceConnectDelegate.remove(iBinder);
                iBinder.unlinkToDeath(this, 0);
              }
            },
            0);
      } catch (RemoteException e) {
        e.printStackTrace();
      }
      delegate = new ServiceConnectionDelegate(base, intent.getComponent());
      sServiceConnectDelegate.put(iBinder, delegate);
    }
    return delegate;
  }

  @Override
  public void connected(ComponentName name, IBinder service) throws RemoteException {
    connected(name, service, false);
  }

  public void connected(ComponentName name, IBinder service, boolean dead) throws RemoteException {
    if (BuildCompat.isOreo()) {
      BRIServiceConnectionO.get(mConn).connected(mComponentName, service, dead);
    } else {
      mConn.connected(name, service);
    }
  }
}
